package sql

import (
	"context"
	"log"
	"time"

	"vov.cx/lib/env"

	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

const (
	keyDBDriver = "DB_DRIVER"
	keyDBDsn    = "DB_DSN"
	keyDBDebug  = "DB_DEBUG"
	keyEnabled  = "DB_ENABLED"
)

var gormDB *gorm.DB
var locCST = time.FixedZone("CST", 3600*8)

func init() {
	if !env.IsTrue(keyEnabled) {
		return
	}

	var (
		dri  = env.GetString(keyDBDriver, "mysql")
		dsn  = env.GetString(keyDBDsn, "root:root@tcp(mysql:3306)/wen_fyi")
		dbg  = env.IsTrue(keyDBDebug)
		dial gorm.Dialector
	)

	if dsn != "" {
		switch dri {
		case "sqlite":
			dial = dialSqlite(dsn)
		case "mysql":
			dial = dialMysql(dsn)
		case "postgres":
			dial = dialPostgres(dsn)
		}
	}

	if dial == nil {
		log.Fatalf("sql: can not found driver: %q with dsn: %q", dri, dsn)
		return
	}

	db, err := gorm.Open(dial, defaultOption())
	if err != nil {
		log.Fatalf("sql: open database error: driver: %q with dsn: %q: %v", dri, dsn, err)
		return
	}
	if dbg {
		gormDB = db.Debug()
	} else {
		gormDB = db
	}
}

func Get(ctx context.Context) *gorm.DB {
	if gormDB == nil {
		return nil
	}
	return gormDB.WithContext(ctx)
}

func defaultOption() gorm.Option {
	gc := &gorm.Config{
		SkipDefaultTransaction: true,
		NamingStrategy:         schema.NamingStrategy{SingularTable: true, NoLowerCase: true},
		NowFunc:                func() time.Time { return time.Now().In(locCST) },
		PrepareStmt:            true,
		DisableAutomaticPing:   true,
		QueryFields:            true,
		CreateBatchSize:        100,
	}
	gc.DisableForeignKeyConstraintWhenMigrating = true
	return gc
}
